package com.sundog.sundroid.google;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;


/**
 * @author pbourdeaux
 * @author <a target="_blank" href="http://www.sundog.net">www.sundog.net</a>
 * @version 1.0,  &nbsp; Oct 2, 2008 11:04:57 AM
 */
public class GoogleService {
	
	public static String auth_token = "";
	
	static Map<String, String> errorMap = new HashMap<String, String>() {
		
        /** */
		private static final long serialVersionUID = 8243818428111745597L;

		{
            put("Error=BadAuthentication", "The username or password was not recognized.");
            put("Error=NotVerified", "The account email address has not been verified. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application.");
            put("Error=TermsNotAgreed", "The user has not agreed to terms. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application. ");
            put("Error=CaptchaRequired", "A CAPTCHA is required.  At this time Sundroid does not support CAPTCHA.");
            put("Error=Unknown", "Unknown Error while attempting to log in.");
            put("Error=AccountDeleted", "The user account has been deleted.");
            put("Error=AccountDisabled", "The user account has been disabled.");
            put("Error=ServiceDisabled", "The user's access to the specified service has been disabled. (The user account may still be valid.) ");
            put("Error=ServiceUnavailable", "The service is not available; try again later.");
        }
    };
    
    public static String extractTokenFromResponse(String token, InputStream response) {
        String result = null;
        String tokenPrefix = (new StringBuilder()).append(token).append("=").toString();
        try {
            InputStreamReader in = new InputStreamReader(response);
            BufferedReader bin = new BufferedReader(in);
            String text = bin.readLine();
            while (text != null) {
                int startIdx = text.indexOf(tokenPrefix);
                if (startIdx >= 0) {
                    int endIdx = text.indexOf('\n', startIdx);
                    if (endIdx > 0) {
                        result = text.substring(startIdx + tokenPrefix.length(),
                                endIdx);
                    } else {
                        result = text.substring(startIdx + tokenPrefix.length());
                    }
                }
                text = bin.readLine();
            }
        } catch (IOException ioe) {
            Log.e("Could not read Token", ioe.getMessage(), ioe);
        }
        auth_token = result;
        return result;
    }
    public static void putUsers(String id) {
    	//PUT http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/cell/version
    	id = id.replace("http://spreadsheets.google.com/feeds/spreadsheets/private/full/", "");
    	String googleUrlStarter = "http://spreadsheets.google.com/feeds/cells/";
    	StringBuilder builder = new StringBuilder();
    	StringBuilder receiver = new StringBuilder();
    	String worksheetid = "od7/";
    	String visibility = "private/";
    	String projection = "full/";
    	
    	builder.append(googleUrlStarter).append(id).append("/").append(worksheetid).append(visibility).append(projection).append("r5c5");
    	String Url = builder.toString();
    	Log.e("GoogleServices", "THE PUT IS RUNNING");
    	HttpClient httpclient;
    	try {
    		httpclient = new DefaultHttpClient();
    		HttpGet get = new HttpGet(Url);
    		get.setHeader("Content-Type", "application/atom+xml");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
    		get.setHeader("Authorization", "GoogleLogin auth=" + auth_token);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"
    	}catch (Exception e1) {
    		Log.e("GoogleServices", e1.toString(), e1);
		}
    }
    public static  Map<String, String> returnStorys (String id){
    	//http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full
    	id = id.replace("http://spreadsheets.google.com/feeds/spreadsheets/private/full/", "");
    	String googleUrlStarter = "http://spreadsheets.google.com/feeds/cells/";
    	StringBuilder builder = new StringBuilder();	//Helps build the URL
    	StringBuilder receiver = new StringBuilder();	//Helps build the response from the cell

    	String contents = "";							//what the method will return
    	String visibility = "private/";					// Sets the visibility to Private
    	String projection = "full";					    // Choice of displaying everything in the cell "full" or "basic which shows everything but formulas
    	String worksheetid = "od6/";
    	String cellRange = "?min-row=3&min-col=2&max-col=2";

    	builder.append(googleUrlStarter).append(id).append("/").append(worksheetid).append(visibility).append(projection).append(cellRange);
    	String Url = builder.toString();

    	HttpClient httpclient;

    	try {
    		httpclient = new DefaultHttpClient();
    		HttpGet get = new HttpGet(Url);
    		get.setHeader("Content-Type", "application/x-www-form-urlencoded");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
    		get.setHeader("Authorization", "GoogleLogin auth=" + auth_token);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"

    		HttpResponse res = httpclient.execute(get);	

    		InputStreamReader in = new InputStreamReader(res.getEntity().getContent()); //Intakes all the data returned from executing httpGet
    		BufferedReader bin = new BufferedReader(in);
    		String text = bin.readLine();												//TEXT becomes all the data sent back from the URL
    		while (text != null) {
    			receiver.append(text);													//receiver becomes all the text put together
    			text = bin.readLine();
    			}
    		}catch (Exception e1) {
    		Log.e("GoogleServices", e1.toString(), e1);
    		}
    		
    	contents = receiver.toString();
    	Document document = documentBuilder(contents);
    	return parseDocument(document);
    	//Log.d("retrun cells", contents);
    	//return contents;
    }
    public static  Map<String, String> returnDetails (String id){
    	//http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full
    	id = id.replace("http://spreadsheets.google.com/feeds/spreadsheets/private/full/", "");
    	String googleUrlStarter = "http://spreadsheets.google.com/feeds/cells/";
    	StringBuilder builder = new StringBuilder();	//Helps build the URL
    	StringBuilder receiver = new StringBuilder();	//Helps build the response from the cell

    	String contents = "";							//what the method will return
    	String visibility = "private/";					// Sets the visibility to Private
    	String projection = "full";					    // Choice of displaying everything in the cell "full" or "basic which shows everything but formulas
    	String worksheetid = "od6/";
    	String cellRange = "?min-row=3&min-col=3&max-col=3";

    	builder.append(googleUrlStarter).append(id).append("/").append(worksheetid).append(visibility).append(projection).append(cellRange);
    	String Url = builder.toString();

    	HttpClient httpclient;

    	try {
    		httpclient = new DefaultHttpClient();
    		HttpGet get = new HttpGet(Url);
    		get.setHeader("Content-Type", "application/x-www-form-urlencoded");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
    		get.setHeader("Authorization", "GoogleLogin auth=" + auth_token);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"

    		HttpResponse res = httpclient.execute(get);	

    		InputStreamReader in = new InputStreamReader(res.getEntity().getContent()); //Intakes all the data returned from executing httpGet
    		BufferedReader bin = new BufferedReader(in);
    		String text = bin.readLine();												//TEXT becomes all the data sent back from the URL
    		while (text != null) {
    			receiver.append(text);													//receiver becomes all the text put together
    			text = bin.readLine();
    			}
    		}catch (Exception e1) {
    		Log.e("GoogleServices", e1.toString(), e1);
    		}
    		
    	contents = receiver.toString();
    	Document document = documentBuilder(contents);
    	return parseDocument(document);
    	//Log.d("retrun cells", contents);
    	//return contents;
    }

    public static  Map<String, String> returnMod (String id){
    	//http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full
    	id = id.replace("http://spreadsheets.google.com/feeds/spreadsheets/private/full/", "");
    	String googleUrlStarter = "http://spreadsheets.google.com/feeds/cells/";
    	
    	StringBuilder builder = new StringBuilder();	//Helps build the URL
    	StringBuilder receiver = new StringBuilder();	//Helps build the response from the cell

    	String contents = "";							//what the method will return
    	String visibility = "private/";					// Sets the visibility to Private
    	String projection = "full";					    // Choice of displaying everything in the cell "full" or "basic which shows everything but formulas
    	String worksheetid = "od7/";
    	String cellRange = "?range=A2";

    	builder.append(googleUrlStarter).append(id).append("/").append(worksheetid).append(visibility).append(projection).append(cellRange);
    	String Url = builder.toString();

    	HttpClient httpclient;

    	try {
    		httpclient = new DefaultHttpClient();
    		HttpGet get = new HttpGet(Url);
    		get.setHeader("Content-Type", "application/x-www-form-urlencoded");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
    		get.setHeader("Authorization", "GoogleLogin auth=" + auth_token);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"

    		HttpResponse res = httpclient.execute(get);	

    		InputStreamReader in = new InputStreamReader(res.getEntity().getContent()); //Intakes all the data returned from executing httpGet
    		BufferedReader bin = new BufferedReader(in);
    		String text = bin.readLine();												//TEXT becomes all the data sent back from the URL
    		while (text != null) {
    			receiver.append(text);													//receiver becomes all the text put together
    			text = bin.readLine();
    			}
    		}catch (Exception e1) {
    		Log.e("GoogleServices", e1.toString(), e1);
    		}
    		
    	contents = receiver.toString();
    	
    	Document document = documentBuilder(contents);
    	
    	return parseDocument(document);
    }
    
    
    public static  Map<String, String> returnUserList (String id){
    	//http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full
    	id = id.replace("http://spreadsheets.google.com/feeds/spreadsheets/private/full/", "");
    	String googleUrlStarter = "http://spreadsheets.google.com/feeds/cells/";
    	StringBuilder builder = new StringBuilder();	//Helps build the URL
    	StringBuilder receiver = new StringBuilder();	//Helps build the response from the cell

    	String contents = "";							//what the method will return
    	String visibility = "private/";					// Sets the visibility to Private
    	String projection = "full";					    // Choice of displaying everything in the cell "full" or "basic which shows everything but formulas
    	String worksheetid = "od7/";
    	String cellRange = "?min-row=5&min-col=1&max-col=1";

    	builder.append(googleUrlStarter).append(id).append("/").append(worksheetid).append(visibility).append(projection).append(cellRange);
    	String Url = builder.toString();

    	HttpClient httpclient;

    	try {
    		httpclient = new DefaultHttpClient();
    		HttpGet get = new HttpGet(Url);
    		get.setHeader("Content-Type", "application/x-www-form-urlencoded");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
    		get.setHeader("Authorization", "GoogleLogin auth=" + auth_token);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"

    		HttpResponse res = httpclient.execute(get);	

    		InputStreamReader in = new InputStreamReader(res.getEntity().getContent()); //Intakes all the data returned from executing httpGet
    		BufferedReader bin = new BufferedReader(in);
    		String text = bin.readLine();												//TEXT becomes all the data sent back from the URL
    		while (text != null) {
    			receiver.append(text);													//receiver becomes all the text put together
    			text = bin.readLine();
    			}
    		}catch (Exception e1) {
    		Log.e("GoogleServices", e1.toString(), e1);
    		}
    		
    	contents = receiver.toString();
    	Document document = documentBuilder(contents);
    	return parseDocument(document);
    	//Log.d("retrun cells", contents);
    	//return contents;
    }
    public static Map<String, String> returnList (String id, String ws) {
    	// GET http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full
    	
    	id = id.replace("http://spreadsheets.google.com/feeds/spreadsheets/private/full/", "");
    	String googleUrlStarter = "http://spreadsheets.google.com/feeds/list/";
    	StringBuilder builder = new StringBuilder();	//Helps build the URL
    	StringBuilder receiver = new StringBuilder();	//Helps build the response from the cell

    	String contents = "";							//what the method will return
    	String visibility = "private/";					// Sets the visibility to Private
    	String projection = "full";					    // Choice of displaying everything in the cell "full" or "basic which shows everything but formulas
    	//Worksheet id fallows this od6 = sheet1, od7 = sheet2, od8 = sheet 3, ....., etc
    	String worksheetid = "od6/";
    	builder.append(googleUrlStarter).append(id).append("/").append(worksheetid).append(visibility).append(projection);
    	String Url = builder.toString();

    	HttpClient httpclient;

    	try {
    		httpclient = new DefaultHttpClient();
    		HttpGet get = new HttpGet(Url);
    		get.setHeader("Content-Type", "application/x-www-form-urlencoded");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
    		get.setHeader("Authorization", "GoogleLogin auth=" + auth_token);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"

    		HttpResponse res = httpclient.execute(get);	

    		InputStreamReader in = new InputStreamReader(res.getEntity().getContent()); //Intakes all the data returned from executing httpGet
    		BufferedReader bin = new BufferedReader(in);
    		String text = bin.readLine();												//TEXT becomes all the data sent back from the URL
    		while (text != null) {
    			receiver.append(text);													//receiver becomes all the text put together
    			text = bin.readLine();
    			}
    		}catch (Exception e1) {
    		Log.e("GoogleServices", e1.toString(), e1);
    		}
    		
    	contents = receiver.toString();
    	Document document = documentBuilder(contents);
    	return parseDocument(document);
    	
    }
    public static Map<String, String> getSpreadsheets(String authToken) {

        HttpClient httpclient;
        StringBuilder builder = new StringBuilder();									//Helps build the string with .appends so it is a complete string
        try {
            String googleAccountUrl = "http://spreadsheets.google.com/feeds/spreadsheets/private/full";
            
            
            httpclient = new DefaultHttpClient(); 								 		//Creates a new instance of httpClient
            HttpGet get = new HttpGet(googleAccountUrl);						 		//takes the URL "googleAccountUrl" and gets the document that it points too
            get.setHeader("Content-Type", "application/x-www-form-urlencoded");	 		//Replaces the header "Content-Type" with "application/x-www-form-urlencoded"
            get.setHeader("Authorization", "GoogleLogin auth=" + authToken);	 		//Replaces the header "Authorization" with "GoogleLogin auth=" + authToken"

            HttpResponse res = httpclient.execute(get);							 		//executes the httpGet

            InputStreamReader in = new InputStreamReader(res.getEntity().getContent()); //Intakes all the data returned from executing httpGet
            BufferedReader bin = new BufferedReader(in);
            String text = bin.readLine();												//TEXT becomes all the data sent back from the URL
            while (text != null) {
                builder.append(text);													//Builder becomes all the text put together
                text = bin.readLine();
            }

        } catch (Exception e1) {
            Log.e("GoogleServices", e1.toString(), e1);
        }

        System.setProperty("javax.xml.parsers.DocumentBuilderFactory",					//what?
                "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
        String input = builder.toString();
        Document document = documentBuilder(input);														
        return parseDocument(document);							//sends to PARSE DOCUMENT before returning
        												 
    }
    private static Document documentBuilder(String input) {
    	DocumentBuilder dBuilder;														//bridge from XML sources to DOM trees
        Document document = null;														//represents the ROOT of the document

        try {
            dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            document = dBuilder.parse(new InputSource(new StringReader(input)));  //document becomes a DOM tree of the text?
        } catch (ParserConfigurationException e) {
            Log.e("Error Parsing Spreadsheets", e.getMessage(), e);
        } catch (IOException e) {
            Log.e("Error Parsing Spreadsheets", e.getMessage(), e);
        } catch (SAXException e) {
            Log.e("Error Parsing Spreadsheets", e.getMessage(), e);
        }
        return document;	
    }
    private static Map<String, String> parseDocument(Document document) {
    	
    	Map<String, String> entries = new HashMap<String, String>();  				//Creates a HASHMAP called entries
        if (document != null) {
            Node feedElement = document.getDocumentElement();						//gets a Root Nodes
            NodeList feedChildNodes = feedElement.getChildNodes();					//gets the Child Nodes from the Root
            
            for (int feedChildIndex = 0; feedChildIndex < feedChildNodes.getLength(); feedChildIndex++) {
                Node feedChild = feedChildNodes.item(feedChildIndex);
                String nodeName = feedChild.getNodeName();
             
                if ("entry".equals(nodeName)) {
                    NodeList entryChildNodes = feedChild.getChildNodes();
                    String title = "";
                    String id = "";
                
                    for (int entryChildIndex = 0; entryChildIndex < entryChildNodes.getLength(); entryChildIndex++) {
                        Node entryChild = entryChildNodes.item(entryChildIndex);
                        String entryNodeName = entryChild.getNodeName();
                      
                    
                        if ("id".equals(entryNodeName)) {
                            id = entryChild.getFirstChild().getNodeValue();
                            Log.d("Sheet Info", "id = " + id);
                       }else if ("content".equals(entryNodeName)) {
                    	   title = (entryChild.getFirstChild().getNodeValue());
                    	   Log.d("sheet Info", "content = " + title);
                       }
                       
                    }
                    entries.put(title, id);
                }
            }
        }
        return entries;
    }
    public static String convertResponseToString(InputStream response) {        StringBuilder builder = new StringBuilder();
        try {
            InputStreamReader in = new InputStreamReader(response);
            BufferedReader bin = new BufferedReader(in);
            String text = bin.readLine();
            while (text != null) {
                builder.append(text).append("\n");
                text = bin.readLine();
            }
        } catch (IOException ioe) {
            Log.e("Could not read Token", ioe.getMessage(), ioe);
        }
        return builder.toString();
    }
    public static CharSequence explainErrorCode(String errorCode) {
        Log.i("map size", "" + errorMap.size());
        return errorMap.get(errorCode.replaceAll("\n", ""));
    }
}
